package reflect;

import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * java 反射机制
 * 反射是java的动态机制,它允许我们在程序[运行期间]再确定对象实例化的操作,以及方法
 * 调用,属性赋值等.这大大的提高了代码的灵活度,但是同时也带来了更多的系统开销和较慢的
 * 运行效率.
 * 因此反射不能过度的被使用.
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            反射机制的第一步,获取要操作的类的类对象
            Class类.该类的每一个实例称为类对象,JVM加载一个类时就会同时实例化一个
            Class的实例与之对应,使用这个Class实例保存加载的类的一切信息.那么这个
            Class实例就称为被加载的类的类对象.

            获取一个类的类对象方式有三种:
            1:类名.class
              Class cls = String.class;
              Class cls = int.class;
              注:基本类型要想获取类对象只有上述方式.

            2:Class.forName(String className)
              使用Class的静态方法并指定要加载的类的完全限定名(包名.类名)
              的方式得到该类的类对象
              Class cls = Class.forName("java.lang.String");

            3:类加载器ClassLoader方式
         */

        //获取String的类对象
//        Class cls = String.class;
//        Class cls = Person.class;
        /*
            reflect.Person
            java.lang.String
            java.util.HashMap
         */
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个类名:");
        String className = scanner.nextLine();
        Class cls = Class.forName(className);


        //通过获取的String对应的类对象,可以获取到String的相关信息
        String name = cls.getName();//获取类的完全限定名
        System.out.println(name);
        name = cls.getSimpleName();
        System.out.println(name);

        //获取包名
        String packageName = cls.getPackage().getName();
        System.out.println(packageName);

        /*
            Method类,该类的每一个实例用于表示一个方法.
            我们通过方法对象可以获取其表示的方法中的相关信息:
            方法名,返回值类型,参数列表,访问修饰符
         */
        //获取所有的方法(包含的是所有公开方法,与超类继承的方法)
//        Method[] methods = cls.getMethods();
        //获取本类定义的方法(包含私有方法,但是不包含超类继承的方法)
        Method[] methods = cls.getDeclaredMethods();
        for(Method method : methods){
            System.out.println("方法名:"+method.getName());
        }




    }
}






